package public

import (
	"crypto/sha256"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/e421083458/golang_common/lib"
	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
	uuid "github.com/satori/go.uuid"
	"strings"
	"time"
)

// CreateUUid 生成uuid
func CreateUUid() string {
	return uuid.NewV4().String()
}

// GenSaltPassword 加盐秘钥
func GenSaltPassword(salt, password string) string {
	s1 := sha256.New()
	s1.Write([]byte(password))
	str1 := fmt.Sprintf("%x", s1.Sum(nil))
	s2 := sha256.New()
	s2.Write([]byte(str1 + salt))
	return fmt.Sprintf("%x", s1.Sum(nil))
}

// JWTInfo 中包含的信息
type JWTInfo struct {
	Id       int64  `json:"id"`
	DeptId   int64  `json:"dept_id"`
	UserName string `json:"user_name"`
	jwt.StandardClaims
}

// GenToken 生成JWT
func GenToken(userId int64, userName string, deptId int64) (string, error) {
	c := JWTInfo{
		Id:       userId,
		UserName: userName,
		DeptId:   deptId,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Hour * time.Duration(lib.GetIntConf("base.jwt.expire"))).Unix(),
			Issuer:    "live_home",
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	return token.SignedString([]byte(lib.GetStringConf("base.jwt.secret")))
}

// ParseToken 解析
func ParseToken(tokenString string) (*JWTInfo, error) {
	token, err := jwt.ParseWithClaims(tokenString, &JWTInfo{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(lib.GetStringConf("base.jwt.secret")), nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*JWTInfo); ok && token.Valid {
		return claims, nil
	}
	return nil, errors.New("invalid token")
}

// RequestValidateToken 解析token
func RequestValidateToken(c *gin.Context) error {
	//这里假设Token放在header的Authorization中并使用Bearer开头
	authHeader := c.GetHeader("Authorization")
	if authHeader == "" {
		return errors.New("身份验证失效")
	}
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "Bearer") {
		return errors.New("身份验证失效")
	}

	mc, err := ParseToken(parts[1])
	if err != nil {
		return errors.New("身份验证失效")
	}
	c.Set("userInfo", mc)
	return nil
}

// GetOpenIdByHeader 从header中获取openId
func GetOpenIdByHeader(c *gin.Context) error {
	authHeader := c.GetHeader("Authorization")
	if authHeader == "" {
		return errors.New("身份验证失效")
	}
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "Bearer") {
		return errors.New("身份验证失效")
	}
	c.Set("user_openId", parts[1])
	return nil
}
